package ph.com.gs3.formalistics.model.vo.parsers.json;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import ph.com.gs3.formalistics.global.constants.StarMark;
import ph.com.gs3.formalistics.model.vo.business.document.Document;
import ph.com.gs3.formalistics.model.vo.business.document.DocumentAction;
import ph.com.gs3.formalistics.model.vo.business.form.FormFieldData;

public class DocumentsJSONParser {

	public static final Document createFromJSON(JSONObject raw, List<FormFieldData> formFields)
	        throws JSONException {

		Document document = new Document();

		document.setWebId(raw.getString("ID"));
		document.setTrackingNumber(raw.getString("TrackNo"));

		document.setStatus(raw.getString("Status"));

		document.setDateCreated(raw.getString("DateCreated"));
		document.setDateUpdated(raw.getString("DateUpdated"));

		// {{ Field Configuration
		String fieldsEnabledStringRaw = raw.getString("fieldEnabled");
		String fieldsRequiredStringRaw = raw.getString("fieldRequired");
		String fieldsHiddenStringRaw = raw.getString("fieldHiddenValues");

		JSONArray fieldsEnabledRaw;
		if (fieldsEnabledStringRaw != null && !fieldsEnabledStringRaw.isEmpty()
		        && !"null".equals(fieldsEnabledStringRaw)) {
			fieldsEnabledRaw = new JSONArray(fieldsEnabledStringRaw);
		} else {
			fieldsEnabledRaw = new JSONArray();
		}

		JSONArray fieldsRequiredRaw;
		if (fieldsRequiredStringRaw != null && !fieldsRequiredStringRaw.isEmpty()
		        && !"null".equals(fieldsRequiredStringRaw)) {
			fieldsRequiredRaw = new JSONArray(fieldsRequiredStringRaw);
		} else {
			fieldsRequiredRaw = new JSONArray();
		}

		JSONArray fieldsHiddenRaw;
		if (fieldsHiddenStringRaw != null && !fieldsHiddenStringRaw.isEmpty()
		        && !"null".equals(fieldsHiddenStringRaw)) {
			fieldsHiddenRaw = new JSONArray(fieldsHiddenStringRaw);
		} else {
			fieldsHiddenRaw = new JSONArray();
		}

		List<String> fieldsEnabled = JSONParser.createStringListFromJSONArray(fieldsEnabledRaw);
		List<String> fieldsRequired = JSONParser.createStringListFromJSONArray(fieldsRequiredRaw);
		List<String> fieldsHidden = JSONParser.createStringListFromJSONArray(fieldsHiddenRaw);

		document.setFieldsEnabled(fieldsEnabled);
		document.setFieldsRequired(fieldsRequired);
		document.setFieldsHidden(fieldsHidden);
		// }}

		// Actions
		String actionsStringRaw = raw.getString("LastAction");
		if (actionsStringRaw != null && !actionsStringRaw.isEmpty()
		        && !"null".equals(actionsStringRaw)) {
			JSONObject actionsRaw = new JSONObject(actionsStringRaw);
			document.setActions(createActionFromDocumentActions(actionsRaw));
		} else {
			// Assign an empty list of actions if there are not actions found
			document.setActions(new ArrayList<DocumentAction>());
		}

		// document.setFieldValues(createFieldValuesFromJSON(raw, formFields));
		document.setFieldValuesJSON(createFieldValuesFromJSON(raw, formFields));

		int isStarredInt = raw.getInt("is_starred");
		StarMark starMark = isStarredInt == 1 ? StarMark.STARRED : StarMark.UNSTARRED;
		document.setStarMark(starMark);

		return document;

	}

	public static JSONObject createFieldValuesFromJSON(JSONObject raw, List<FormFieldData> formFields)
	        throws JSONException {

		JSONObject filteredJSONFields = new JSONObject();
		for (FormFieldData formField : formFields) {
			String key = formField.getId();
			if (raw.has(key)) {
				filteredJSONFields.put(key, raw.getString(key));
			}
		}

		return filteredJSONFields;

	}

	private static List<DocumentAction> createActionFromDocumentActions(JSONObject raw) {

		List<DocumentAction> actions = new ArrayList<>();

		Iterator<?> iterator = raw.keys();
		int keyCount = 0;

		while (iterator.hasNext()) {
			String key = (String) iterator.next();
			keyCount++;
			try {
				JSONObject actionFromLastAction = new JSONObject(raw.getString(key));

				// Throws JSONException
				DocumentAction action = new DocumentAction();

				action.setLabel(key);
				action.setAction(actionFromLastAction.getString("child_id"));

				actions.add(action);
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}

		if (keyCount > 0) {
			// Add save and cancel
			DocumentAction save = new DocumentAction();
			DocumentAction cancel = new DocumentAction();

			save.setLabel("Save");
			save.setAction("Save");

			cancel.setLabel("Cancel");
			cancel.setAction("Cancel");

			actions.add(save);
			actions.add(cancel);

		}

		return actions;

	}

}
